/**
 * 
 */
package cx3k.dataAccess;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.Session;
import org.hibernate.Transaction;

import cx3k.scheduler.objects.Course;
import cx3k.scheduler.objects.Major;
import cx3k.scheduler.objects.Minor;
import cx3k.scheduler.objects.Semester;

/**
 * @author Chris
 *
 */
public abstract class CX3KDatabaseManager<T> extends DatabaseManager<T> {

	private static final String GET_ALL_MAJORS = "from Major as major";
	private static final String GET_ALL_MINORS = "from Minor as minor";
	private static final String GET_ALL_COURSES = "from Course as course";
	private static final String WHERE_COURSE_ID = " where course.courseId = ";
	private static final String GET_ALL_SEMESTERS = "from Semester as semester";
	
	protected static Map<Integer, Major> getAllMajors(){
		return createMajorMapping(getMajorsFromDatabase());
	}
	
	protected static Map<Integer, Minor> getAllMinors(){
		return createMinorMapping(getMinorsFromDatabase());
	}
	
	protected static Map<Integer, Course> getAllCourses(){
		return createCourseMapping(getCoursesFromDatabase());
	}
	
	protected static Map<Integer, Semester> getAllSemesters(){
		return createSemesterMapping(getSemestersFromDatabase());
	}
	
	protected static Course getCourse(int courseId){
		return getCourseFromDatabase(courseId);
	}
	
	@SuppressWarnings("unchecked")
	private static Course getCourseFromDatabase(int courseId){
		
		Course ret = null;
		
		Session session = getSession();
		Transaction tx = session.beginTransaction();
		
		List<Course> courses = (List<Course>) session.createQuery(GET_ALL_COURSES + WHERE_COURSE_ID + " = " + courseId).list();
		
		if(!courses.isEmpty()){
			ret = courses.get(0);
		}
		
		tx.commit();
		session.close();
		
		return ret;
	}
	
	@SuppressWarnings("unchecked")
	private static List<Major> getMajorsFromDatabase(){
		
		Session session = getSession();
		Transaction tx = session.beginTransaction();
		
		List<Major> majors = (List<Major>) session.createQuery(GET_ALL_MAJORS).list();
		
		tx.commit();
		session.close();
		
		return majors;
	}
	
	@SuppressWarnings("unchecked")
	private static List<Minor> getMinorsFromDatabase(){
		
		Session session = getSession();
		Transaction tx = session.beginTransaction();
		
		List<Minor> minors = (List<Minor>) session.createQuery(GET_ALL_MINORS).list();
		
		tx.commit();
		session.close();
		
		return minors;
	}
	
	@SuppressWarnings("unchecked")
	private static List<Course> getCoursesFromDatabase(){
		
		Session session = getSession();
		Transaction tx = session.beginTransaction();
		
		List<Course> courses = (List<Course>) session.createQuery(GET_ALL_COURSES).list();
		
		tx.commit();
		session.close();
		
		return courses;
	}
	
	@SuppressWarnings("unchecked")
	private static List<Semester> getSemestersFromDatabase(){
		
		Session session = getSession();
		Transaction tx = session.beginTransaction();
		
		List<Semester> semesters = (List<Semester>) session.createQuery(GET_ALL_SEMESTERS).list();
		
		tx.commit();
		session.close();
		
		return semesters;
	}
	
	private static Map<Integer, Major> createMajorMapping(List<Major> majors){
		Map<Integer, Major> mappedMajors = new HashMap<Integer, Major>();
		
		for(Major major : majors){
			mappedMajors.put(major.getMajorId(), major);
		}
		
		return mappedMajors;
	}
	
	private static Map<Integer, Minor> createMinorMapping(List<Minor> minors){
		Map<Integer, Minor> mappedMinors = new HashMap<Integer, Minor>();
		
		for(Minor minor : minors){
			mappedMinors.put(minor.getMinorId(), minor);
		}
		
		return mappedMinors;
	}
	
	private static Map<Integer, Course> createCourseMapping(List<Course> courses){
		Map<Integer, Course> mappedCourses = new HashMap<Integer, Course>();
		
		for(Course course : courses){
			mappedCourses.put(course.getCourseId(), course);
		}
		
		return mappedCourses;
	}
	
	private static Map<Integer, Semester> createSemesterMapping(List<Semester> semesters){
		Map<Integer, Semester> mappedSemesters = new HashMap<Integer, Semester>();
		
		for(Semester semester : semesters){
			mappedSemesters.put(semester.getSemesterId(), semester);
		}
		
		return mappedSemesters;
	}
}
